/*
 * PluginManager.java
 *
 * Created on Sep 24, 2009, 11:52:17 PM
 */

package net.sf.bluex.boundary;

import java.io.File;
import java.util.Vector;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableModel;
import net.sf.bluex.components.BlueXStatics;
import net.sf.bluex.components.HelpMapper;
import net.sf.bluex.components.Updater;
import net.sf.bluex.controller.FileModule;
import net.sf.bluex.controller.UsefulMethods;
import net.sf.bluex.plugin.PluginMetaData;
import net.sf.bluex.plugin.Version;
import net.sf.bluex.threads.InterruptableThread;

/**
 *
 * @author Blue
 */
public class PluginManager extends javax.swing.JFrame implements Runnable {

    private InterruptableThread t;

    private int threadType;

    private Vector<PluginMetaData> vectInstalledPlugins;

    private Vector<PluginMetaData> vectDownloadedFilePlugins;

    private Vector<PluginMetaData> vectNewPlugins=new Vector<PluginMetaData>(), vectPluginUpates=new Vector<PluginMetaData>();

    private Updater upd=new Updater();

    public static PluginManager pm;
    
    /** Creates new form PluginManager */
    private PluginManager() {
        initComponents();

        initInstalledPlugins();

        jProgressBar1.setVisible(false);

        jTextArea1.requestFocus();

        //make invisible buttons
        jButton8.setVisible(false);
        jButton3.setVisible(false);

        //set icon
        this.setIconImage(net.sf.bluex.controller.UsefulMethods.getImage(net.sf.bluex.controller.FileModule.APP_ICON));
        setLocationByPlatform(true);
    }

    public static void showPluginManager(){
        if(pm==null)
            pm=new PluginManager();
        if(pm.isVisible())
            pm.requestFocus();
        else
            pm.setVisible(true);
    }

    public static boolean isManagerVisible(){
        return pm!=null && pm.isVisible();
    }

    public static void updateStatus(boolean status){
        if(status)
            pm.jProgressBar1.setString("Fetching From Server");
        pm.jProgressBar1.setVisible(status);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        jButton3 = new javax.swing.JButton();
        jButton8 = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        jTable2 = new javax.swing.JTable();
        jButton4 = new javax.swing.JButton();
        jButton5 = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane4 = new javax.swing.JScrollPane();
        jTable3 = new javax.swing.JTable();
        jButton6 = new javax.swing.JButton();
        jButton7 = new javax.swing.JButton();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        jLabel1 = new javax.swing.JLabel();
        jProgressBar1 = new javax.swing.JProgressBar();
        jLabel2 = new javax.swing.JLabel();

        setTitle("Plugins");

        jPanel1.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentShown(java.awt.event.ComponentEvent evt) {
                jPanel1ComponentShown(evt);
            }
        });

        jTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Name", "Version", "Size"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jTable1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTable1MouseClicked(evt);
            }
        });
        jScrollPane2.setViewportView(jTable1);

        jButton3.setText("Install New");
        jButton3.setToolTipText("Install New Plugin from Plugin File");
        jButton3.setEnabled(false);
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        jButton8.setText("Uninstall");
        jButton8.setToolTipText("Uninstall Selected Plugins");
        jButton8.setEnabled(false);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jButton8)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 197, Short.MAX_VALUE)
                        .addComponent(jButton3)))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 319, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton3)
                    .addComponent(jButton8))
                .addContainerGap())
        );

        jTabbedPane1.addTab("Installed", jPanel1);

        jPanel2.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentShown(java.awt.event.ComponentEvent evt) {
                jPanel2ComponentShown(evt);
            }
        });

        jTable2.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Name", "Version", "Size"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jTable2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTable2MouseClicked(evt);
            }
        });
        jScrollPane3.setViewportView(jTable2);

        jButton4.setText("Download Selected");
        jButton4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton4ActionPerformed(evt);
            }
        });

        jButton5.setText("Refresh");
        jButton5.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton5ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(jButton5)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 161, Short.MAX_VALUE)
                        .addComponent(jButton4)))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 319, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton4)
                    .addComponent(jButton5))
                .addContainerGap())
        );

        jTabbedPane1.addTab("Available Plugins", jPanel2);

        jPanel3.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentShown(java.awt.event.ComponentEvent evt) {
                jPanel3ComponentShown(evt);
            }
        });

        jTable3.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Name", "Version", "Size"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jTable3.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTable3MouseClicked(evt);
            }
        });
        jScrollPane4.setViewportView(jTable3);

        jButton6.setText("Update Selected");
        jButton6.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton6ActionPerformed(evt);
            }
        });

        jButton7.setText("Refresh");
        jButton7.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton7ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane4, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addComponent(jButton7)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 173, Short.MAX_VALUE)
                        .addComponent(jButton6)))
                .addContainerGap())
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 319, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton6)
                    .addComponent(jButton7))
                .addContainerGap())
        );

        jTabbedPane1.addTab("Updates", jPanel3);

        jButton1.setText("Help");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jButton2.setText("Hide");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jTextArea1.setColumns(20);
        jTextArea1.setEditable(false);
        jTextArea1.setLineWrap(true);
        jTextArea1.setRows(5);
        jTextArea1.setWrapStyleWord(true);
        jScrollPane1.setViewportView(jTextArea1);

        jLabel1.setText("Description:");

        jProgressBar1.setIndeterminate(true);
        jProgressBar1.setString("Fetching From Server");
        jProgressBar1.setStringPainted(true);

        jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/net/sf/bluex/resources/answer.gif"))); // NOI18N
        jLabel2.setText("Click on each plugin to get their info.");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 380, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addComponent(jLabel2)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 379, Short.MAX_VALUE)))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 507, Short.MAX_VALUE)
                        .addComponent(jButton2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton1)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel2)))
                .addGap(10, 10, 10)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButton1)
                    .addComponent(jButton2))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jPanel2ComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_jPanel2ComponentShown
        // TODO add your handling code here:
        if(vectDownloadedFilePlugins==null)
            refreshDownloadedData();
        jTable2MouseClicked(null);
}//GEN-LAST:event_jPanel2ComponentShown

    private void jPanel3ComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_jPanel3ComponentShown
        // TODO add your handling code here:
        if(vectDownloadedFilePlugins==null)
            refreshDownloadedData();
        jTable3MouseClicked(null);
}//GEN-LAST:event_jPanel3ComponentShown

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        // TODO add your handling code here:
        this.setVisible(false);
    }//GEN-LAST:event_jButton2ActionPerformed

    private void jButton7ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton7ActionPerformed
        // TODO add your handling code here:
        refreshDownloadedData();
    }//GEN-LAST:event_jButton7ActionPerformed

    private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton5ActionPerformed
        // TODO add your handling code here:
        refreshDownloadedData();
    }//GEN-LAST:event_jButton5ActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        // TODO add your handling code here:
        HelpMapper.showHelpFor("Plugin Manager");
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed
        // TODO add your handling code here:
        if(jTable2.getSelectedRow()!=-1){
            boolean download=t==null;
            if(t!=null)
                download=!t.isAlive();

            if(download){
                threadType=2;
                t=InterruptableThread.getMyThread(this, "Downloading the New Plugins");
                t.start();
            }else
                JOptionPane.showMessageDialog(this, "Another Network Thread is working.\nPlease wait.");
        }
    }//GEN-LAST:event_jButton4ActionPerformed

    private void jButton6ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton6ActionPerformed
        // TODO add your handling code here:
        if(jTable3.getSelectedRow()!=-1){
            boolean download=t==null;
            if(t!=null)
                download=!t.isAlive();

            if(download){
                threadType=3;
                t=InterruptableThread.getMyThread(this, "Downloading the Updates");
                t.start();
            }else
                JOptionPane.showMessageDialog(this, "Another Network Thread is working.\nPlease wait.");
        }
    }//GEN-LAST:event_jButton6ActionPerformed

    private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTable1MouseClicked
        // TODO add your handling code here:
        int row=jTable1.getSelectedRow();
        if(row!=-1){
            jTextArea1.setText(vectInstalledPlugins.elementAt(row).toString());
        }else
            jTextArea1.setText("");
    }//GEN-LAST:event_jTable1MouseClicked

    private void jTable2MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTable2MouseClicked
        // TODO add your handling code here:
        int row=jTable2.getSelectedRow();
        if(row!=-1){
            jTextArea1.setText(vectNewPlugins.elementAt(row).toString());
        }else
            jTextArea1.setText("");
    }//GEN-LAST:event_jTable2MouseClicked

    private void jTable3MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTable3MouseClicked
        // TODO add your handling code here:
        int row=jTable3.getSelectedRow();
        if(row!=-1){
            jTextArea1.setText(vectPluginUpates.elementAt(row).toString());
        }else
            jTextArea1.setText("");
    }//GEN-LAST:event_jTable3MouseClicked

    private void jPanel1ComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_jPanel1ComponentShown
        // TODO add your handling code here:
        jTable1MouseClicked(null);
    }//GEN-LAST:event_jPanel1ComponentShown

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
        JFileChooser jfc=new JFileChooser();
        jfc.setFileFilter(new FileNameExtensionFilter("BlueX Plugin File (.bxp)", "bxp"));
        int choice=jfc.showOpenDialog(pm);
        if(choice==jfc.APPROVE_OPTION){
            File file=jfc.getSelectedFile();
            installPluginFromFile(file);
        }
    }//GEN-LAST:event_jButton3ActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JButton jButton6;
    private javax.swing.JButton jButton7;
    private javax.swing.JButton jButton8;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JProgressBar jProgressBar1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JTable jTable1;
    private javax.swing.JTable jTable2;
    private javax.swing.JTable jTable3;
    private javax.swing.JTextArea jTextArea1;
    // End of variables declaration//GEN-END:variables


    private void initInstalledPlugins() {
        DefaultTableModel dtm=(DefaultTableModel)jTable1.getModel();
        vectInstalledPlugins=new Vector<PluginMetaData>(UsefulMethods.getAllInstalledPlugins());
        for(PluginMetaData pmd : vectInstalledPlugins)
            dtm.addRow(new String[]{pmd.getName(), pmd.getVersion().toString(), UsefulMethods.getFileSize(pmd.getSize())});
    }

    private void initAvailablePlugins() {
        DefaultTableModel dtm=(DefaultTableModel)jTable2.getModel();

        //remove all first
        for(int last=dtm.getRowCount()-1; last>=0; last--)
            dtm.removeRow(last);

        dwnload: for(PluginMetaData dwnldPMD : vectNewPlugins)
            dtm.addRow(new String[]{dwnldPMD.getName(), dwnldPMD.getVersion().toString(), UsefulMethods.getFileSize(dwnldPMD.getSize())});
    }

    private void initUpdatablePlugins() {
        DefaultTableModel dtm=(DefaultTableModel)jTable3.getModel();

        //remove all first
        for(int last=dtm.getRowCount()-1; last>=0; last--)
            dtm.removeRow(last);
        
        for(PluginMetaData dwnldPMD : vectPluginUpates)
            dtm.addRow(new String[]{dwnldPMD.getName(), dwnldPMD.getVersion().toString(), UsefulMethods.getFileSize(dwnldPMD.getSize())});
    }

    private void refreshDownloadedData() {
        if(t==null || !t.isAlive()){
            threadType=1;
            t=InterruptableThread.getMyThread(this, "Plugin Manager Refreshing Thread");
            t.start();
        }else
            JOptionPane.showMessageDialog(this, "The refreshing task is already under progress.\n" +
                    "Please wait.");
    }

    public void run() {
        if(threadType==1){//fetching data
            upd.refreshDownloadedData();
            while(upd.isAlive());//wait yaar
            vectDownloadedFilePlugins=upd.getVectDownloadedFilePlugins();
            vectNewPlugins=upd.getVectNewPlugins();
            vectPluginUpates=upd.getVectPluginUpates();
        }else if(threadType==2){//downloading new plugins
            int[] selectedRows=jTable2.getSelectedRows();
            Vector<PluginMetaData> vectPMD=new Vector<PluginMetaData>(selectedRows.length);
            for(int i : selectedRows)
                vectPMD.add(vectNewPlugins.elementAt(i));
            installAlgo(vectPMD, threadType, false);
        }else{//updating plugins
            int[] selectedRows=jTable3.getSelectedRows();
            Vector<PluginMetaData> vectPMD=new Vector<PluginMetaData>(selectedRows.length);
            for(int i : selectedRows)
                vectPMD.add(vectPluginUpates.elementAt(i));
            installAlgo(vectPMD, threadType, false);
        }

        initAvailablePlugins();
        initUpdatablePlugins();
    }

    private void startDownloads(boolean b) {
        jButton5.setEnabled(!b);
        jButton7.setEnabled(!b);
        jProgressBar1.setString("Downloading From Server");
        jProgressBar1.setVisible(b);
    }

    private void installAlgo(Vector<PluginMetaData> vectPMD, int mode, boolean externallyCalled){
        int successCount=0;
        startDownloads(true);
        for(PluginMetaData selectedPMD : vectPMD){
            if(Version.compareVersions(new Version(BlueXStatics.prop.getProperty("bluexversion")), selectedPMD.getMinimumBaseWindowVersion())!=Version.LESSER){//check for minimum version
                String urlSource=FileModule.SERVER_URL+selectedPMD.getName()+PluginMetaData.EXTENSION;
                String destination=FileModule.DOWNLOAD_FOLDER+File.separatorChar+selectedPMD.getName()+selectedPMD.EXTENSION;
                if(UsefulMethods.downloadFile(urlSource, destination, UsefulMethods.HTTP_PROTOCOL)){
                    if(mode==2){
                        if(UsefulMethods.installNewPlugin(selectedPMD, destination)){
                            if(!externallyCalled)
                                //remove enteries from table
                                vectNewPlugins.removeElement(selectedPMD);
                            //increment successcount
                            successCount++;
                        }
                    }else if(mode==3){
                        if(UsefulMethods.installUpdateOfPlugin(selectedPMD, destination)){
                            if(!externallyCalled)
                                //remove enteries from table
                                vectPluginUpates.removeElement(selectedPMD);
                            //increment successcount
                            successCount++;
                        }
                    }
                }
            }else
                JOptionPane.showMessageDialog(this, "The plugin: "+selectedPMD.getName()+"\nrequires a higher version of BlueX.\n" +
                        "Please download the new version by going to the:\n" +
                    "Help->Visit BlueX Home Page", "BlueX Version Error", JOptionPane.ERROR_MESSAGE);
        }
        startDownloads(false);

        if(successCount==0)
            JOptionPane.showMessageDialog(this, "There is some fatal error as none of the selected\n" +
                    "plugins have been installed.", "Error in Downloading", JOptionPane.ERROR_MESSAGE);
        else
            JOptionPane.showMessageDialog(this, successCount+" out of "+vectPMD.size()+" Plugin(s) have been " +
                    "successfully installed.\n\nPlease restart BlueX to see them effective.");
    }

    public static void installPluginFromFile(File file){
        JOptionPane.showMessageDialog(null, "This service is currently not working properly.\n" +
                "Install this plugin using the Plugin Manager by downloading it from the Server.\n" +
                "Sorry for inconvenience.", "BlueX- Installer Service Not Working", JOptionPane.ERROR_MESSAGE);
        return;
        //the file name should be equal to PluginName.bxp
        //as the installed plugins will be mapped using this name only...

////        {
////        String pluginName=file.getName().substring(0, file.getName().lastIndexOf('.'));
////        File extractedSource=new File(FileModule.EXTRACTED_TEMP_FOLDER+File.separatorChar+pluginName);
////        if(extractedSource.exists() || extractedSource.mkdir()){
////            if(UsefulMethods.extractCompressedFile(file.getAbsolutePath(), extractedSource)){
////                File pluginXML=new File(FileModule.EXTRACTED_TEMP_FOLDER+File.separatorChar+pluginName+File.separatorChar+pluginName+".xml");
////                PluginMetaData pmd=UsefulMethods.getPluginsFromFile(pluginXML.getAbsolutePath()).elementAt(0);
////
////                if(Version.compareVersions(new Version(BlueXStatics.prop.getProperty("bluexversion")), pmd.getMinimumBaseWindowVersion())!=Version.LESSER){//check for minimum version
////
////                    boolean exist=false;
////                    for(PluginMetaData temp : UsefulMethods.getAllInstalledPlugins())
////                        if(temp.equals(pmd)){
////                            exist=true;
////                            break;
////                        }
////
////                    boolean successful=true;
////                    if(exist){
////                        //do update the plugin
////                        successful=UsefulMethods.installUpdateOfPlugin(pmd, file.getAbsolutePath());
////                    }else{
////                        //do install new plugin
////                        successful=UsefulMethods.installNewPlugin(pmd, file.getAbsolutePath());
////                    }
////
////                    if(successful)
////                        JOptionPane.showMessageDialog(null, "The plugin have been successfully installed.", "Congratulations!!!", JOptionPane.INFORMATION_MESSAGE);
////                    else
////                        JOptionPane.showMessageDialog(null, "There is some error while installing the plugin.", "Installation Error", JOptionPane.ERROR_MESSAGE);
////                }else
////                JOptionPane.showMessageDialog(null, "The BlueX installed on your system is old. It does not supports\n" +
////                        "this plugin. Please download the new version by going to the:\n" +
////                        "Help->Visit BlueX Home Page", "BlueX Version Error", JOptionPane.ERROR_MESSAGE);
////            }
////        }
////        }
    }
}
